#ifndef CONNECTION_H_
#define CONNECTION_H_

#include "base/base.h"

namespace rpc {
struct Event;
class Buffer;
class Socket;
class Protocol;
class ProtoAttr;
class EventManager;

class Connection {
  public:
    Connection(EventManager* ev_mgr, Socket* socket);
    ~Connection();

    void SetCloseClosure(Closure* closure) {
      CHECK(closure != NULL);
      close_closure_.reset(closure);
    }
    void SetProtocol(Protocol* protocol) {
      CHECK_NOTNULL(protocol);
      protocol_ = protocol;
    }
    void SetAttr(ProtoAttr* attr) {
      CHECK_NOTNULL(attr);
      attr_.reset(attr);
    }
    ProtoAttr* GetAttr() const {
      CHECK_NOTNULL(attr_.get());
      return attr_.get();
    }

    const Socket* getSocket() const {
      return socket_.get();
    }

    bool Send(const u_char* buf, uint32 buf_len);
    int32 Recv(uint32 size);

    bool Init();

    void HandleRead();
    void HandleWrite();
    void HandleClose();
    void HandleError();

    void ShutDown();

  private:
    EventManager* ev_mgr_;
    scoped_ptr<Socket> socket_;
    scoped_ptr<Buffer> input_buf_;
    scoped_ptr<Buffer> output_buf_;

    scoped_ptr<Event> ev_;
    Protocol* protocol_;
    scoped_ptr<ProtoAttr> attr_;
    scoped_ptr<Closure> close_closure_;

    DISALLOW_COPY_AND_ASSIGN(Connection);
};

}

#endif

